import logging
from logging.handlers import RotatingFileHandler

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import generate_csrf
from redis import StrictRedis
from flask_wtf import CSRFProtect
from flask_session import Session
# 导入配置信息字典
from config import config
from info.utils.common import RegexConverter


def set_log(config_name):
    """
    创建日志文件
    :param config_name: 配置环境名
    """
    # 1 > 设置日志的记录等级
    logging.basicConfig(level=config[config_name].LOG_LEVEL)    # 调试debug级
    # 2 > 创建日志记录器, 指明日志保存的路径, 每个日志文件的大小, 保存的日志文件个数上限
    file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 100, backupCount=10)
    # 3 > 创建日志记录的格式,日志等级,输入日志信息的文件名,行数,日志信息
    formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
    # 4 > 为创建的日志记录器设置日志记录格式
    file_log_handler.setFormatter(formatter)
    # 5 > 为全局的日志工具对象（flask app使用的）添加日志记录器
    logging.getLogger().addHandler(file_log_handler)


# 创建sql数据库实例 db = SQLAlchemy(app) <==> db = SQLAlchemy() db.init_app(app)
db = SQLAlchemy()
# 创建 redis 存储对象, 连接 redis 数据库, 默认 host='localhost', port=6379, db=0
redis_store = None


def create_app(config_name):
    """
    # 封装 app db 实例
    :param config_name: 配置环境名
    :return: app 实例
    """
    # 创建实例前开启日志
    set_log(config_name)

    # 创建Flask实例
    app = Flask(__name__)
    # 1> app实例 关联配置信息类
    app.config.from_object(config[config_name])
    # 2> app实例 连接 mysql 数据库
    db.init_app(app)
    # 3> 创建 redis 存储对象, 连接 redis 数据库
    global redis_store
    redis_store = StrictRedis(host=config[config_name].REDIS_HOST, port=config[config_name].REDIS_PORT, decode_responses='True')

    # 4> 开启 CSRF 保护
    @app.after_request
    def after_request(response):
        csrf_token = generate_csrf()
        # 将csrf_token值存在cookie中, 返回给浏览器
        response.set_cookie('csrf_token', csrf_token)
        return response

    CSRFProtect(app)
    # 5> 将 session 保存到 redis 中
    Session(app)

    # 定义正则转换器
    app.url_map.converters['re'] = RegexConverter

    # 注册 访问静态文件的蓝图
    from info.modules.web_html import html_blu
    app.register_blueprint(html_blu)

    from info.modules.index import index_blu
    app.register_blueprint(index_blu)
    # 注册 的蓝图
    from info.modules.api_v1 import api_blu
    app.register_blueprint(api_blu)

    from info.modules.profile import pro_blu
    app.register_blueprint(pro_blu)

    from info.modules.orders import order_blu
    app.register_blueprint(order_blu)

    from info.modules.house_list import house_list_blu
    app.register_blueprint(house_list_blu)
    # 注册用户实名认证的蓝图
    from info.modules.verify import verify_blu
    app.register_blueprint(verify_blu)

    from info.modules.newhouse import new_house_blu
    app.register_blueprint(new_house_blu)

    from info.modules.detail import detail_blu
    app.register_blueprint(detail_blu)

    from info.modules.release_house_check import check_house_blu
    app.register_blueprint(check_house_blu)

    return app


if __name__ == '__main__':
    create_app('develop')